package com.weasel.weixin.commons.accounts;

import com.google.common.collect.ImmutableMap;
import com.weasel.http.HttpClientSecretary;
import com.weasel.http.SimpleHttpUploadAndDownloadSecretary;
import com.weasel.http.handler.DownloadHandler;
import com.weasel.http.helper.HttpUrlHelper;
import com.weasel.weixin.commons.AccessTokenRequest;
import com.weasel.weixin.commons.CommonRequest;
import com.weasel.weixin.commons.config.CommonConfig;
import com.weasel.weixin.commons.config.CommonConsts;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.CloseableHttpResponse;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

/**
 * Created by Dylan on 2015/10/14.
 */
public class QRCodeRequest  extends CommonRequest {


    public QRCodeRequest(CommonConfig config) {
        super(config);
    }

    /**
     * 获取临时二维码
     * @param seconds  该二维码有效时间，以秒为单位。 最大不超过604800（即7天）。
     * @param sceneId  场景值ID，临时二维码时为32位非0整型，永久二维码时最大值为100000（目前参数只支持1--100000）
     * @return
     * @throws IOException
     * @throws ExecutionException
     */
    public QRCoceResponse getTemporaryQRCode(int seconds,int sceneId) throws IOException, ExecutionException {

        Map<String,Object> params = new HashMap<>();
        params.put("expire_seconds",seconds);
        params.put("action_name","QR_SCENE");
        params.put("action_info", ImmutableMap.of("scene", ImmutableMap.of("scene_id", sceneId)));

        return createQRCode(params);
    }

    /**
     * 获取临时二维码(有效期为二分钟)
     * @param sceneId 场景值ID，临时二维码时为32位非0整型，永久二维码时最大值为100000（目前参数只支持1--100000）
     * @return
     * @throws IOException
     * @throws ExecutionException
     */
    public QRCoceResponse getTemporaryQRCode(int sceneId) throws IOException, ExecutionException {

        return getTemporaryQRCode(120, sceneId);
    }

    /**
     * 获取永久二维码
     * @param sceneStr 场景值ID（字符串形式的ID），字符串类型，长度限制为1到64，仅永久二维码支持此字段
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public QRCoceResponse getForeverQRCode(String sceneStr) throws ExecutionException, IOException {

        Map<String,Object> params = new HashMap<>();
        params.put("action_name","QR_LIMIT_STR_SCENE");
        params.put("action_info", ImmutableMap.of("scene", ImmutableMap.of("scene_str", sceneStr)));

        return createQRCode(params);
    }

    /**
     * 获取永久二维码
     * @param sceneId 场景值ID，临时二维码时为32位非0整型，永久二维码时最大值为100000（目前参数只支持1--100000）
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public QRCoceResponse getForeverQRCode(int sceneId) throws ExecutionException, IOException {

        Map<String,Object> params = new HashMap<>();
        params.put("action_name","QR_LIMIT_SCENE");
        params.put("action_info", ImmutableMap.of("scene", ImmutableMap.of("scene_id", sceneId)));

        return createQRCode(params);
    }


    /**
     * 获取二维码图片到本地
     * @param ticket 二维码ticket，凭借此ticket可以在有效时间内换取二维码。
     * @param fileDirectory  二维码图片文件的保存目录
     * @return
     * @throws IOException
     */
    public File getQRCode(String ticket, final File fileDirectory) throws IOException {

        String url = getQRCodeImageURL(ticket);
        File file = SimpleHttpUploadAndDownloadSecretary.download(url, new DownloadHandler<File>() {
            @Override
            public File handler(CloseableHttpResponse response, InputStream fileInputStream) {
                File tempFile = null;
                try {
                    tempFile = File.createTempFile(UUID.randomUUID().toString(), ".jpg", fileDirectory);
                    FileUtils.copyInputStreamToFile(fileInputStream,tempFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return tempFile;
            }
        });

        return file;
    }

    /**获取二维码的图片地址，页面可以用<img>标示显示
     * @param ticket 二维码ticket，凭借此ticket可以在有效时间内换取二维码。
     * @return
     * @throws UnsupportedEncodingException
     */
    public String getQRCodeImageURL(String ticket) throws UnsupportedEncodingException {

        String url = HttpUrlHelper.withURL(CommonConsts.DOWNLOAD_QRCODE_URL).addParam("ticket",URLEncoder.encode(ticket,"utf-8")).build();
        return url;
    }

    /**
     *
     * @return
     * @throws ExecutionException
     */
    private String getUrl() throws ExecutionException {
        String accessToken = new AccessTokenRequest(config).getAccessToken();
        String url = HttpUrlHelper.withURL(CommonConsts.QUCODE_URL).addParam("access_token", accessToken).build();
        return url;
    }

    /**
     * @param params
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    private QRCoceResponse createQRCode(Map<String,Object> params) throws ExecutionException, IOException {
        QRCoceResponse response = HttpClientSecretary.post()
                                                     .withURI(getUrl())
                                                     .withParam(params)
                                                     .doItWithJson(QRCoceResponse.class);

        return response;
    }
}
